#include "BoomBarrel.h"
#include "EventSystem.h"
#include "GamePlayState.h"
#include "EmitterManager.h"
#include "Level.h"
#include "Room.h"

int BoomBarrel::Explosion = -1;
unsigned int BoomBarrel::Count = 0;

// Constructor
BoomBarrel::BoomBarrel(void) : Destroyed(false), e(nullptr)
{
	HzType = HZ_BARREL;

	// Set the image part
	image.left = 0;
	image.right = 32;
	image.top = 32;
	image.bottom = 64;

	SetWidth(32);
	SetHeight(32);

	// Use events to cause destruction
	EventSystem::GetInstance()->RegisterClient("target_hit", this);

	// Make the master emitter if necessary
	if( Explosion == -1 )
		Explosion = EmitterManager::GetInstance()->CreateEmitterTemplate(Emitter::LoadEmitter("Emitters/enemydeath.xml"));

	// Create the individual emitter
	e = EmitterManager::GetInstance()->CreateEmitterFromTemplate(Explosion);
	e->SetEmissionRate(20);

	Count++;

}

// Destructor
BoomBarrel::~BoomBarrel(void) 
{
	if( --Count == 0 )
	{
		//EmitterManager::GetInstance()->DestroyTemplate(Explosion);
		Explosion = -1;
	}
	//Bug Fix #8 && #20 && #71 Start - Brandon Jones
	EventSystem::GetInstance()->UnregisterClientAll(this);
	// Bug Fix #8 && #20 && #71 End - Brandon Jones
	e->Shutdown();
	delete e;
}

// Draw
void BoomBarrel::Render(void)
{
	// Get the camera
	int camx = GamePlayState::GetInstance()->GetCamX();
	int camy = GamePlayState::GetInstance()->GetCamY();

	// Don't draw if it's off screen
	if( GetX() < camx || GetY() < camy || GetX() > camx + 800 || GetY() > camy + 600)
		return;

	// Render the particles
	if( e->HasParticles() )
		e->Render();

	// Don't do anything else if it was destroyed
	if( Destroyed ) 
		return;

	// Do the basic rendering
	Hazard::Render();

}

// Update
void BoomBarrel::Update(float elapasedTime)
{
	// Update the particles
	if( e->HasParticles() || e->IsBursting())
		e->Update(elapasedTime);
}

// Collision Response
bool BoomBarrel::CheckCollision(IEntity* base)
{
	return false;
}

// For exploding
void BoomBarrel::HandleEvent(Event* thisEvent)
{
	if(thisEvent->GetParameter() != this)
		return;

	if( thisEvent->GetEventID() == "target_hit" )
	{
		Destroyed = true;
		SetHeight(0);
		SetWidth(0);
		e->SetPosition(GetX(),GetY());
		e->Burst();
		// Find all the enemies nearby and damage them
		if( GamePlayState::GetInstance()->GetLevel() )
		{
			vector<Enemy*> enemies = GamePlayState::GetInstance()->GetLevel()->GetRoom(roomNumber)->GetEnemyVec();
			for(unsigned int i = 0; i < enemies.size(); ++i)
			{
				int xdist = (int)(enemies[i]->GetX() - GetX());
				int ydist = (int)(enemies[i]->GetY() - GetY());
				if( sqrt((float)xdist*xdist + (float)ydist*ydist) < 128 )
					enemies[i]->SetHealth(enemies[i]->GetHealth() - 50);
			}
		}
		// Also hurt nearby players
		if( GamePlayState::GetInstance()->GetPlayer() )
		{
			Player* p1 = GamePlayState::GetInstance()->GetPlayer();
			int xdist = (int)(p1->GetX() - GetX());
			int ydist = (int)(p1->GetY() - GetY());
			if( sqrt((float)xdist*xdist + (float)ydist*ydist) < 128 )
				GamePlayState::GetInstance()->GetPlayer()->TakeDam(50);
		}
		if( GamePlayState::GetInstance()->GetPlayer2() )
		{
			Player* p2 = GamePlayState::GetInstance()->GetPlayer2();
			int xdist = (int)(p2->GetX() - GetX());
			int ydist = (int)(p2->GetY() - GetY());
			if( sqrt((float)xdist*xdist + (float)ydist*ydist) < 128 )
				GamePlayState::GetInstance()->GetPlayer2()->TakeDam(50);
		}
	}
}